package com.dmzapp.api.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dmzapp.api.cache.local.LocalCache;
import com.dmzapp.api.db.AppDao;
import com.dmzapp.api.util.Constant;
import com.dmzapp.api.util.StringUtils;
import com.dmzapp.api.vo.UserAccount;

public class ValidateFilter implements Filter {

    Logger logger = LoggerFactory.getLogger("dmzlog");

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    public String getRemortIP(HttpServletRequest request) {

        if (request.getHeader("x-forwarded-for") == null) {

            return request.getRemoteAddr();

        }

        return request.getHeader("x-forwarded-for");

    }

    /**
     * 用于验证用户是否合法，并且包含注册逻辑
     * 
     * 特殊情况：一个用户可以在两台手机上分别用qq和sina登录，这种情况的特殊性在于每个登录授权是一条独立的记录，不能相互登录
     * 
     * 用例详解： 1.
     * 注册：用户第一次安装，微博授权登录，注册操作（判断条件：macaddress和deviceid联合查询没有对应记录，qq或sina授权登录的uid也没有对应记录）
     * 2. 登录授权：用户第二次登录，也是用微博授权，则检查mac地址+deviceid是否与库中匹配，如匹配则验证成功 3.
     * 登录授权：用户第三次登录，换做qq授权登录，此时库中只有微博+mac+deviceid信息，如果qq在全库中不存在，则应该为这条记录加入qq信息，并授权成功
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {

        if(((HttpServletRequest)request).getRequestURI().contains("download_apk") ||
                ((HttpServletRequest)request).getRequestURI().contains("download_count")){
            chain.doFilter(request, response);
            return;
        }
        
        
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String deviceid = request.getParameter("d");
        String macAddress = request.getParameter("m");
        String ip = request.getParameter("i");

        String nickname = request.getParameter("nn");

        String authType = request.getParameter("at");
        // qq号或者新浪uid
        String authUid = request.getParameter("uid");

        String location = request.getParameter("location");
        String sex = request.getParameter("sex");
        String bornDate = request.getParameter("born");
        
        PrintWriter writer = response.getWriter();
        boolean validate = false;

        String username = null;
        int userTypeInSystem = -1;
        if (StringUtils.isNullOrEmpty(deviceid) || StringUtils.isNullOrEmpty(macAddress)
                || StringUtils.isNullOrEmpty(ip) || StringUtils.isNullOrEmpty(authType)
                || StringUtils.isNullOrEmpty(authUid)) {
            StringBuilder sb = new StringBuilder();
            sb.append("deviceid: ").append(deviceid);
            sb.append("macAddress: ").append(macAddress);
            sb.append("ip: ").append(ip);
            sb.append("authType: ").append(authType);
            sb.append("authUid: ").append(authUid);
            logger.warn("Invalid request", sb.toString());
            // 非法请求,参数不全
            validate = false;
            writer.write("参数不全");
        } else {
            // mac地址或者device其中一个匹配就算是有重复
            boolean macDeviceExist = true;
            if (!LocalCache.getInstance().macAddressCache.contains(macAddress)
                    && !LocalCache.getInstance().deviceidCache.contains(deviceid)) {
                // 两个都不存在才去数据库中查询
                UserAccount tmp = AppDao.getInstance().getMacDevice(macAddress, deviceid);
                if (tmp != null) {
                    LocalCache.getInstance().macAddressCache.add(tmp.getMac_address());
                    LocalCache.getInstance().deviceidCache.add(tmp.getDeviceid());
                    username = tmp.getUsername();
                    userTypeInSystem = tmp.getUser_type();
                    macDeviceExist = true;
                } else {
                    macDeviceExist = false;
                }
            } else {
                macDeviceExist = true;
            }

            UserAccount accountFromUid = new UserAccount();
            if (authType.equals(Constant.AUTH_QQ_TYPE)) {

                boolean qqExist = true;
                String macdeviceStr = LocalCache.getInstance().qqUserCache.get(authUid);
                if (StringUtils.isNullOrEmpty(macdeviceStr)) {

                    accountFromUid = AppDao.getInstance().getMacDeviceidByqq(authUid);
                    if (accountFromUid != null) {
                        // 有的话加入缓存
                        LocalCache.getInstance().qqUserCache.put(authUid, accountFromUid.getMac_address() + ","
                                + accountFromUid.getDeviceid() + "," + accountFromUid.getUser_type() + ","
                                + accountFromUid.getUsername());
                        userTypeInSystem = accountFromUid.getUser_type();
                        username = accountFromUid.getUsername();
                        qqExist = true;
                    } else {
                        qqExist = false;
                    }
                } else {
                    qqExist = true;
                    String[] macdeviceValue = macdeviceStr.split(",");
                    if (macdeviceValue != null && macdeviceValue.length == 4) {
                        accountFromUid.setMac_address(macdeviceValue[0]);
                        accountFromUid.setDeviceid(macdeviceValue[1]);
                        userTypeInSystem = Integer.valueOf(macdeviceValue[2]);
                        username = macdeviceValue[3];
                    }
                }

                if (accountFromUid == null) {
                    accountFromUid = new UserAccount();
                }
                if (qqExist && macAddress.equals(accountFromUid.getMac_address())
                        && deviceid.equals(accountFromUid.getDeviceid())) {
                    // qq存在， mac地址和deviceid也匹配
                    validate = true;
                } else if (qqExist
                        && (!macAddress.equals(accountFromUid.getMac_address()) || !deviceid.equals(accountFromUid
                                .getDeviceid()))) {
                    // qq存在，但是mac地址跟deviceid不匹配
                    validate = false;
                    writer.write("同一个qq不能在多台手机上绑定哦");
                } else if (!qqExist && macDeviceExist) {
                    // qq不存在但是mac地址存在，
                    // 1.说明之前使用新浪微博账号登录，将qq信息插入该条记录
                    // 2.也有可能是在同一台手机上用不同的qq登录,因此要判断
                    if (userTypeInSystem == 1) {
                        // 多个qq号码同时登录
                        writer.write("不能在同一台手机上绑定多个qq号码哦");
                        validate = false;
                    } else {
                        accountFromUid.setQq(authUid);
                        accountFromUid.setQqnickname(nickname);
                        accountFromUid.setMac_address(macAddress);
                        accountFromUid.setDeviceid(deviceid);
                        if (AppDao.getInstance().updateQQinfo4Enduser(accountFromUid)) {
                            validate = true;
                        }
                    }

                } else if (!qqExist && !macDeviceExist) {
                    // qq跟 mac+deviceid都不存在，表示是全新注册

                    accountFromUid.setQq(authUid);
                    accountFromUid.setQqnickname(nickname);
                    accountFromUid.setMac_address(macAddress);
                    accountFromUid.setDeviceid(deviceid);
                    accountFromUid.setUser_type(1);
                    accountFromUid.setUsername(authUid);
                    accountFromUid.setLocation(location);
                    accountFromUid.setSex(sex);
                    accountFromUid.setBornDate(bornDate);
                    if (AppDao.getInstance().insertEnduser(accountFromUid)) {
                        validate = true;
                    }
                }
            } else if (authType.equals(Constant.AUTH_SINA_TYPE)) {
                boolean sinaExist = true;
                String macdeviceStr = LocalCache.getInstance().sinaUserCache.get(authUid);
                if (StringUtils.isNullOrEmpty(macdeviceStr)) {

                    accountFromUid = AppDao.getInstance().getMacDeviceidBysina(authUid);
                    if (accountFromUid != null) {
                        // 有的话加入缓存
                        LocalCache.getInstance().sinaUserCache.put(authUid, accountFromUid.getMac_address() + ","
                                + accountFromUid.getDeviceid() + "," + accountFromUid.getUser_type() + ","
                                + accountFromUid.getUsername());
                        userTypeInSystem = accountFromUid.getUser_type();
                        username = accountFromUid.getUsername();
                        sinaExist = true;
                    } else {
                        sinaExist = false;
                    }
                } else {
                    sinaExist = true;
                    String[] macdeviceValue = macdeviceStr.split(",");
                    if (macdeviceValue != null && macdeviceValue.length == 4) {
                        accountFromUid.setMac_address(macdeviceValue[0]);
                        accountFromUid.setDeviceid(macdeviceValue[1]);
                        userTypeInSystem = Integer.valueOf(macdeviceValue[2]);
                        username = macdeviceValue[3];
                    }

                }

                if (accountFromUid == null) {
                    accountFromUid = new UserAccount();
                }

                if (sinaExist && macAddress.equals(accountFromUid.getMac_address())
                        && deviceid.equals(accountFromUid.getDeviceid())) {
                    // qq存在， mac地址和deviceid也匹配
                    validate = true;
                } else if (sinaExist
                        && (!macAddress.equals(accountFromUid.getMac_address()) || !deviceid.equals(accountFromUid
                                .getDeviceid()))) {
                    // qq存在，但是mac地址跟deviceid不匹配
                    validate = false;
                    writer.write("同一个新浪微博号不能在多台手机上绑定哦");
                } else if (!sinaExist && macDeviceExist) {
                    // sina账号不存在但是mac地址存在，说明之前使用新浪微博账号登录，将qq信息插入该条记录
                    if (userTypeInSystem == 0) {
                        // 多个sina号码同时登录
                        validate = false;
                        writer.write("不能在一台手机上绑定多个新浪微博账号哦");
                    } else {
                        accountFromUid.setWeibouid(authUid);
                        accountFromUid.setWeibonickname(nickname);
                        accountFromUid.setMac_address(macAddress);
                        accountFromUid.setDeviceid(deviceid);
                        if (AppDao.getInstance().updateSinainfo4Enduser(accountFromUid)) {
                            validate = true;
                        }
                    }
                } else if (!sinaExist && !macDeviceExist) {
                    // sina跟 mac+deviceid都不存在，表示是全新注册
                    accountFromUid.setWeibouid(authUid);
                    accountFromUid.setWeibonickname(nickname);
                    accountFromUid.setMac_address(macAddress);
                    accountFromUid.setDeviceid(deviceid);
                    accountFromUid.setUser_type(0);
                    accountFromUid.setUsername(authUid);
                    accountFromUid.setLocation(location);
                    accountFromUid.setSex(sex);
                    accountFromUid.setBornDate(bornDate);
                    if (AppDao.getInstance().insertEnduser(accountFromUid)) {
                        validate = true;
                    }
                }
            }
        }

        if (validate) {

            // 获取username的逻辑
            if (userTypeInSystem == -1) {
                // 第一次注册
                request.setAttribute("u", authUid);
            } else if (username != null) {
                // 验证用户
                request.setAttribute("u", username);
            }

            // 更新一下
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}
